// Copyright 2014 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef V8_COMPILER_PIPELINE_H_
#define V8_COMPILER_PIPELINE_H_

// Clients of this interface shouldn't depend on lots of compiler internals.
// Do not include anything from src/compiler here!
#include "src/globals.h"
#include "src/objects.h"
#include "src/objects/code.h"

namespace v8 {
namespace internal {

    struct AssemblerOptions;
    class OptimizedCompilationInfo;
    class OptimizedCompilationJob;
    class RegisterConfiguration;

    namespace wasm {
        struct FunctionBody;
        class NativeModule;
        struct WasmCompilationResult;
        class WasmEngine;
        struct WasmModule;
    } // namespace wasm

    namespace compiler {

        class CallDescriptor;
        class Graph;
        class InstructionSequence;
        class JSHeapBroker;
        class MachineGraph;
        class NodeOriginTable;
        class Schedule;
        class SourcePositionTable;

        class Pipeline : public AllStatic {
        public:
            // Returns a new compilation job for the given JavaScript function.
            static OptimizedCompilationJob* NewCompilationJob(Isolate* isolate,
                Handle<JSFunction> function,
                bool has_script);

            // Run the pipeline for the WebAssembly compilation info.
            static void GenerateCodeForWasmFunction(
                OptimizedCompilationInfo* info, wasm::WasmEngine* wasm_engine,
                MachineGraph* mcgraph, CallDescriptor* call_descriptor,
                SourcePositionTable* source_positions, NodeOriginTable* node_origins,
                wasm::FunctionBody function_body, const wasm::WasmModule* module,
                int function_index);

            // Run the pipeline on a machine graph and generate code.
            static wasm::WasmCompilationResult GenerateCodeForWasmNativeStub(
                wasm::WasmEngine* wasm_engine, CallDescriptor* call_descriptor,
                MachineGraph* mcgraph, Code::Kind kind, int wasm_kind,
                const char* debug_name, const AssemblerOptions& assembler_options,
                SourcePositionTable* source_positions = nullptr);

            // Run the pipeline on a machine graph and generate code.
            static MaybeHandle<Code> GenerateCodeForWasmHeapStub(
                Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph,
                Code::Kind kind, const char* debug_name,
                const AssemblerOptions& assembler_options,
                SourcePositionTable* source_positions = nullptr);

            // Run the pipeline on a machine graph and generate code.
            static MaybeHandle<Code> GenerateCodeForCodeStub(
                Isolate* isolate, CallDescriptor* call_descriptor, Graph* graph,
                SourcePositionTable* source_positions, Code::Kind kind,
                const char* debug_name, int32_t builtin_index,
                PoisoningMitigationLevel poisoning_level,
                const AssemblerOptions& options);

            // ---------------------------------------------------------------------------
            // The following methods are for testing purposes only. Avoid production use.
            // ---------------------------------------------------------------------------

            // Run the pipeline on JavaScript bytecode and generate code.
            // If requested, hands out the heap broker, which is allocated
            // in {info}'s zone.
            V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting(
                OptimizedCompilationInfo* info, Isolate* isolate,
                JSHeapBroker** out_broker = nullptr);

            // Run the pipeline on a machine graph and generate code. If {schedule} is
            // {nullptr}, then compute a new schedule for code generation.
            V8_EXPORT_PRIVATE static MaybeHandle<Code> GenerateCodeForTesting(
                OptimizedCompilationInfo* info, Isolate* isolate,
                CallDescriptor* call_descriptor, Graph* graph,
                const AssemblerOptions& options, Schedule* schedule = nullptr);

            // Run just the register allocator phases.
            V8_EXPORT_PRIVATE static bool AllocateRegistersForTesting(
                const RegisterConfiguration* config, InstructionSequence* sequence,
                bool run_verifier);

        private:
            DISALLOW_IMPLICIT_CONSTRUCTORS(Pipeline);
        };

    } // namespace compiler
} // namespace internal
} // namespace v8

#endif // V8_COMPILER_PIPELINE_H_
